package hook

import (
	"fmt"
	"time"

	"wespy-http-go/app/activity/2025/summer_drink_car/conf"
	"wespy-http-go/app/activity/widget/rank/store"
	"wespy-http-go/pkg/weconfig/wenamespace/weactivity"
)

// SummerDrinkCarRankHooker 夏日饮品车排行榜钩子
type SummerDrinkCarRankHooker struct {
	store.DefaultRankCheckoutHooker // 嵌入默认实现
}

// isRankTimeValid 检查当前时间是否在排行榜有效时间内
func isRankTimeValid(actConfig *conf.ActConfig, now time.Time) bool {
	if actConfig.RankStartHour <= 0 || actConfig.RankDurationHour <= 0 {
		return true // 配置无效时默认允许
	}

	currentHour := now.Hour()

	// 检查是否在排行榜时间段内
	if currentHour >= actConfig.RankStartHour {
		// 当天的排行榜时间段内
		return true
	} else {
		// 跨天的情况（0:00-RankStartHour之间）
		// 属于昨天最后一个时间段，即23:00-0:00
		return currentHour < actConfig.RankStartHour
	}
}

// getCurrentRankHour 获取当前时间段的开始小时（用于积分存储）
func getCurrentRankHour(actConfig *conf.ActConfig, now time.Time) int {
	currentHour := now.Hour()

	if currentHour >= actConfig.RankStartHour {
		// 当天的排行榜时间段内
		rankRound := (currentHour - actConfig.RankStartHour) / actConfig.RankDurationHour
		return actConfig.RankStartHour + rankRound*actConfig.RankDurationHour
	} else {
		// 跨天的情况（0:00-RankStartHour之间）
		// 属于昨天最后一个时间段，即23:00-0:00
		return 23
	}
}

// 以下是重写的Hook方法，只重写我们需要自定义的方法

// BeforeIncrRankValue Hook方法实现 - 控制积分的生效时间和过滤条件
func (h *SummerDrinkCarRankHooker) BeforeIncrRankValue(actInfo *weactivity.Activity, rankConfig *weactivity.Rank, periodType int, member string, value int, t time.Time) (store.BeforeIncrValueRsp, error) {
	// 只对口碑排行榜（rankId=1）进行时间控制
	if rankConfig.Type != "1" {
		return store.BeforeIncrValueRsp{Filter: false}, nil // 其他排行榜不过滤
	}

	actConfig := conf.GetActConfig(actInfo)
	if actConfig == nil {
		return store.BeforeIncrValueRsp{Filter: false}, nil
	}

	// 检查是否在排行榜有效时间内
	if !isRankTimeValid(actConfig, t) {
		return store.BeforeIncrValueRsp{Filter: true}, nil // 不在有效时间内，过滤掉积分
	}

	return store.BeforeIncrValueRsp{Filter: false}, nil // 在有效时间内，允许积分增加
}

// BeforeGetTimeFormat 自定义时间格式生成
func (h *SummerDrinkCarRankHooker) BeforeGetTimeFormat(actInfo *weactivity.Activity, rankConf *weactivity.Rank, now time.Time) string {
	// 只对口碑排行榜（rankId=1）应用小时分段逻辑
	if rankConf.Type != "1" {
		return "" // 其他排行榜使用默认逻辑
	}

	actConfig := conf.GetActConfig(actInfo)
	if actConfig == nil || actConfig.RankStartHour <= 0 || actConfig.RankDurationHour <= 0 {
		return ""
	}

	// Hook主要用于积分存储，使用当前时间段
	hour := getCurrentRankHour(actConfig, now)
	timeKey := fmt.Sprintf("%04d%02d%02d%02d", now.Year(), now.Month(), now.Day(), hour)

	return timeKey
}

// BeforeGetRedisKey 自定义Redis Key生成（排行榜列表）
func (h *SummerDrinkCarRankHooker) BeforeGetRedisKey(actInfo *weactivity.Activity, rankConf *weactivity.Rank, t time.Time) string {
	// 只对口碑排行榜（rankId=1）应用小时分段逻辑
	if rankConf.Type != "1" {
		return "" // 其他排行榜使用默认逻辑
	}

	actConfig := conf.GetActConfig(actInfo)
	if actConfig == nil || actConfig.RankStartHour <= 0 || actConfig.RankDurationHour <= 0 {
		return ""
	}

	// Hook主要用于积分存储，使用当前时间段
	hour := getCurrentRankHour(actConfig, t)
	timeKey := fmt.Sprintf("%04d%02d%02d%02d", t.Year(), t.Month(), t.Day(), hour)

	// 生成时间分段的Redis Key
	return fmt.Sprintf("act:rank:list:%d:%s:%s", actInfo.ActId, rankConf.Type, timeKey)
}

// BeforeGetSelfRedisKey 自定义Redis Key生成（个人积分）
func (h *SummerDrinkCarRankHooker) BeforeGetSelfRedisKey(actInfo *weactivity.Activity, rankConf *weactivity.Rank, t time.Time, member string) string {
	// 只对口碑排行榜（rankId=1）应用小时分段逻辑
	if rankConf.Type != "1" {
		return "" // 其他排行榜使用默认逻辑
	}

	actConfig := conf.GetActConfig(actInfo)
	if actConfig == nil || actConfig.RankStartHour <= 0 || actConfig.RankDurationHour <= 0 {
		return ""
	}

	// Hook主要用于积分存储，使用当前时间段
	hour := getCurrentRankHour(actConfig, t)
	timeKey := fmt.Sprintf("%04d%02d%02d%02d", t.Year(), t.Month(), t.Day(), hour)

	// 生成时间分段的Redis Key
	return fmt.Sprintf("act:rank:self:%d:%s:%s:%s", actInfo.ActId, rankConf.Type, timeKey, member)
}

// GetRankCheckoutHooker 获取排行榜结算钩子实例
func GetRankCheckoutHooker() store.RankCheckoutHooker {
	return &SummerDrinkCarRankHooker{}
}
